Management API: Add endpoints to sort the children of a document or media item by a system field#23077
Management API: Add endpoints to sort the children of a document or media item by a system field#23077AndyButland wants to merge 5 commits into
Conversation
|
Claude finished @AndyButland's task in 7m 29s —— View job PR ReviewTarget: Adds four Management API endpoints (
Important
Suggestions
Approved with Suggestions for improvementThis is solid, well-structured work. The design is consistent with existing patterns (controller-per-operation, authorization via |
There was a problem hiding this comment.
Pull request overview
Adds a Management API “auto-arrange” capability for Documents and Media: new PUT .../sort-children endpoints sort a parent’s children (or root-level items) by a selected system field (name/create date/update date) and persist the resulting order as SortOrder, matching list-view/database ordering semantics.
Changes:
- Introduces
ContentSortFieldandSortByFieldAsync(...)on content/media editing services, implemented via shared sorting base logic that loads children ordered by a DBOrderingand then persists that order. - Adds four Management API controllers (document/media + root variants) and corresponding request models + OpenAPI spec entries.
- Adds integration tests covering service-level sorting behavior (content + media) and controller authorization for the new endpoints.
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj | Adds new partial test file to project item metadata (DependentUpon grouping). |
| tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEditingServiceTests.SortByField.cs | Integration tests for content sorting-by-field incl. culture-aware name sorting and root-level case. |
| tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/MediaEditingServiceTests.SortByField.cs | Integration tests for media sorting-by-field scenarios. |
| tests/Umbraco.Tests.Integration/ManagementApi/Document/SortChildrenDocumentControllerTests.cs | Authorization coverage for document {id}/sort-children endpoint. |
| tests/Umbraco.Tests.Integration/ManagementApi/Document/SortChildrenAtRootDocumentControllerTests.cs | Authorization coverage for document root/sort-children endpoint. |
| tests/Umbraco.Tests.Integration/ManagementApi/Media/SortChildrenMediaControllerTests.cs | Authorization coverage for media {id}/sort-children endpoint. |
| tests/Umbraco.Tests.Integration/ManagementApi/Media/SortChildrenAtRootMediaControllerTests.cs | Authorization coverage for media root/sort-children endpoint. |
| src/Umbraco.Core/Models/ContentEditing/ContentSortField.cs | Adds typed enum for supported system sort fields. |
| src/Umbraco.Core/Services/IContentEditingService.cs | Adds SortByFieldAsync to content editing service contract (default interface impl). |
| src/Umbraco.Core/Services/IMediaEditingService.cs | Adds SortByFieldAsync to media editing service contract (default interface impl). |
| src/Umbraco.Core/Services/ContentEditingServiceWithSortingBase.cs | Implements shared HandleSortByFieldAsync and adds ordering-aware child paging. |
| src/Umbraco.Core/Services/ContentEditingService.cs | Wires SortByFieldAsync and passes ordering through to GetPagedChildren. |
| src/Umbraco.Core/Services/MediaEditingService.cs | Wires SortByFieldAsync and passes ordering through to GetPagedChildren. |
| src/Umbraco.Cms.Api.Management/ViewModels/Sorting/SortChildrenByFieldRequestModelBase.cs | Adds base request model containing field and direction for the new endpoints. |
| src/Umbraco.Cms.Api.Management/ViewModels/Sorting/SortDocumentChildrenByFieldRequestModel.cs | Document-specific request model adds optional culture. |
| src/Umbraco.Cms.Api.Management/ViewModels/Sorting/SortMediaChildrenByFieldRequestModel.cs | Media-specific request model (no culture). |
| src/Umbraco.Cms.Api.Management/Controllers/Document/SortChildrenDocumentController.cs | New document-by-id sort-children endpoint + authorization + status mapping. |
| src/Umbraco.Cms.Api.Management/Controllers/Document/SortChildrenAtRootDocumentController.cs | New root document sort-children endpoint + authorization + status mapping. |
| src/Umbraco.Cms.Api.Management/Controllers/Media/SortChildrenMediaController.cs | New media-by-id sort-children endpoint + authorization + status mapping. |
| src/Umbraco.Cms.Api.Management/Controllers/Media/SortChildrenAtRootMediaController.cs | New root media sort-children endpoint + authorization + status mapping. |
| src/Umbraco.Cms.Api.Management/OpenApi.json | Adds the four new paths and request schemas + ContentSortFieldModel. |
|
Claude finished @AndyButland's task in 12m 58s —— View job PR ReviewTarget: Adds 4 Management API endpoints (
Suggestions
Approved with Suggestions for improvementGood to go, but please carefully consider the importance of the suggestions. |
Description
Adds Management API endpoints to sort the children of a node by a chosen system field (name, create date, update date) and direction — an "auto-arrange" that persists the result as the children's sort order. Scoped to Documents and Media.
New endpoints
All take a JSON body and return
200 OKon success,400 Bad Requestif the field is unrecognised, or404 Not Foundif the parent doesn't exist.PUT /umbraco/management/api/v1/document/{id}/sort-childrenPUT /umbraco/management/api/v1/document/root/sort-childrenPUT /umbraco/management/api/v1/media/{id}/sort-childrenPUT /umbraco/management/api/v1/media/root/sort-childrenRequest body:
Handling variants
For variant handling I've looked to match the existing manual drag-drop "sort children" UX, which displays the variant name but the node-level create date.
As such the provided culture only affects sorting by
name. When provided, variant children are ordered by their name in that culture; invariant children, or variant children with no name for that culture, fall back to the invariant name.Create/update dates are node-level, not culture-specific.
Other notes
200).fieldvalues are rejected at model binding (the field is a typed enum), and defensively mapped to400at the service layer.Sorting large numbers of children
The manual drag-and-drop sort is naturally self-limiting: an editor has to load and reorder every child in the client before submitting, so it's impractical to trigger on huge sets. This endpoint is different — it can reorder a node's entire set of children from a single button click, regardless of how many there are, and a field sort typically moves most of them. Reusing the standard per-item sort would mean loading every child into memory and issuing (in the worst case) one
UPDATEand one save/sort notification — and therefore one webhook — per child.To keep this cheap and safe by default, a field sort is persisted differently from the manual sort:
UPDATEin the repository (IContentRepository.UpdateSortOrder, batched only to stay within the SQL Server parameter limit). The editing service collects the ordered child ids by paging — it does not hold every child in memory.umbracoNode.For the small number of cases that depend on those per-item notifications/webhooks, the previous behaviour can be restored with the
Umbraco:CMS:Content:SortChildrenByFieldFiresNotificationssetting (defaultfalse). When enabled, the field sort goes through the standard per-item sort path instead, accepting the additional performance cost on nodes with many children. The combined audit entry and single branch refresh are used in both cases — only the per-item notifications differ.Testing
Automated
Integration tests have been added at the service level to verify the ordering functionality.
Controller authorization tests for all four endpoints are also added.
Manual
Prerequisites: run the site and sign in to the backoffice — this authenticates the Swagger UI via the auth cookie. (Any other client must send the backoffice credentials, i.e.
credentials: include.)Open Swagger UI at
https://localhost:44339/umbraco/swagger/index.html(adjust the port to your launch settings) and select the Management API definition. The new operations are under the Document and Media tags, ending in/sort-children.Set up content to sort. Create a parent document with a handful of children whose names are deliberately out of order (e.g. "Banana", "Apple", "Cherry") and, ideally, different create/update dates. For variant testing, use a culture-varying document type with two languages and give the children different names per culture.
Sort the children of a node —
PUT /umbraco/management/api/v1/document/{id}/sort-children, where{id}is the parent's key:{ "field": "name", "direction": "Ascending" }Expect
200 OK, then refresh the tree / list view under the parent and confirm the new order.Sort root-level items —
PUT /umbraco/management/api/v1/document/root/sort-children(no id), same body.Variant check (documents only). Repeat step 3 with a culture:
{ "field": "name", "direction": "Ascending", "culture": "da-DK" }Confirm the order reflects the Danish names. Call again with
"culture": "en-US"and confirm the order changes to the English names.Dates. Call with
"field": "createDate"or"updateDate"and confirm ordering by the node-level dates (aculturehas no effect on these).Media. Repeat against
/media/{id}/sort-childrenand/media/root/sort-children. The media body has noculture.Error cases.
PUT /document/{random-guid}/sort-children→404 Not Found.{ "field": "bogus", "direction": "Ascending" }→400 Bad Request.Documentation
Need to document the new
SortChildrenByFieldFiresNotificationssetting.Related
References #19703.